<template>
  <div class="demo-block">
    <div class="demo-example">
      <slot></slot>
    </div>
    <div class="demo-details"
      ref="details">
      <div class="demo-description"
        ref="detailDescription"
        v-if="this.$slots.description">
        <p>
          <slot name="description"></slot>
        </p>
      </div>
      <div class="demo-code"
        ref="detailCode">
        <slot name="code"></slot>
      </div>
    </div>
    <div class="demo-block-control"
      @click="handleToogleDetails">
      <i class="demo-icon-arrow"
        :class="{ 'is-bottom': detailsShow }"></i>
      <span class="demo-icon-text">{{ detailsShow ? '隐藏代码' : '显示代码' }}</span>
    </div>
  </div>
</template>

<script>
const toggleHeight = function (el, { speed = 0.3, timing = 'ease-out', callback }) {
  el.style.transition = `height ${speed}s ${timing}`; // 设置动画
  // 初始化高度为 0
  if (el.clientHeight === 0) {
    el.style.height = 'auto';
    const height = el.clientHeight;
    el.style.height = '0px';
    window.setTimeout(() => {
      el.style.height = `${height}px`;
      if (callback) callback(height);
    }, 0);
  } else {
    el.style.height = '0px';
    if (callback) callback(0);
  }
}

export default {
  provide() {
    return {
      calcDetailsHeight: this.calcDetailsHeight,
    };
  },
  props: {
    showDetails: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      detailsShow: this.showDetails,
    };
  },
  methods: {
    handleToogleDetails() {
      const detailsEl = this.$refs.details;
      if (!detailsEl) return;
      toggleHeight(detailsEl, {
        speed: 0.35,
        timing: 'ease-out',
        callback: (height) => {
          if (height) {
            this.detailsShow = true;
          } else {
            this.detailsShow = false;
          }
        },
      })
    },
    calcDetailsHeight() {
      const detailsEl = this.$refs.details;
      const descriptionEl = this.$refs.detailDescription;
      const codeEl = this.$refs.detailCode;
      let height = 0;
      if (descriptionEl) height += descriptionEl.clientHeight + 20;
      if (codeEl) height += codeEl.clientHeight;
      if (!descriptionEl && !codeEl) height = detailsEl.scrollHeight;
      detailsEl.style.height = `${height}px`;
    },
  },
};
</script>

<style lang="stylus">
$theme-color = var(--theme-color)
$icon-color = var(--color-text-light)

.theme-default-content
  .demo-block
    a
      &:hover
        text-decoration: none

.demo-block
  border: 1px solid var(--color-border)
  border-radius: 3px
  transition: 0.2s

  &:hover
    box-shadow: 0 0 8px 0 rgba(232, 237, 250, 60%), 0 2px 4px 0 rgba(232, 237, 250, 50%)

.demo-example
  padding: 24px

.demo-details
  height: 0
  background-color: var(--color-bg-light)
  overflow: hidden
  transition: height 0.2s

.demo-description
  margin: 10px
  padding: 20px
  box-sizing: border-box
  border: 1px solid var(--color-border)
  border-radius: 3px
  font-size: 14px
  color: #666
  word-break: break-word
  background-color: var(--color-bg)

  p
    margin: 0

.demo-block-control
  position: relative
  display: flex
  justify-content: center
  align-items: center
  height: 40px
  line-height: 40px
  background-color: var(--color-bg)
  color: $icon-color
  cursor: pointer
  transition: all 0.3s

  &:hover
    background-color: var(--color-bg-light)
    border-color: $theme-color
    color: $theme-color

.demo-icon-arrow
  display: flex
  align-items: center
  margin-right: 5px
  color: inherit

  &.is-bottom
    transform: rotate(180deg)

  &::before
    content: ''
    border: 7px solid
    border-color: transparent transparent
    border-top-color: inherit
    transform: translateY(25%)

.demo-icon-text
  font-size: 14px
</style>
